feat: add NIP, TUCK, PICK, ROLL stack operations#14
Conversation
tetsuo-cpp
left a comment
There was a problem hiding this comment.
Code Review: feat: add NIP, TUCK, PICK, ROLL stack operations
Overview
Adds four new stack manipulation words across all three layers: ODS table definitions, Forth-to-MLIR translation, and MemRef conversion patterns. PICK and ROLL are dynamic (runtime-indexed), with ROLL using an scf.for shift loop. Clean 282-line addition.
Correctness
All four conversion patterns are correct. Verified each against standard Forth semantics:
- NIP
(a b -- b): Loads top, decrements SP, stores at new SP. ✓ - TUCK
(a b -- b a b): Loads both, rearranges, increments SP. ✓ - PICK
(xn...x0 n -- xn...x0 xn): Pops n, computesSP' - n, loads and pushes. ✓ Edge case0 PICK= DUP works. - ROLL
(xn...x0 n -- xn-1...x0 xn): Pops n, saves target, shifts withscf.for, stores saved at top. ✓ Edge cases:0 ROLL= no-op,1 ROLL= SWAP,2 ROLL= ROT — all verified.
Stack pointer convention (SP points to top element) is consistent with existing patterns.
Code Quality & Style
- Follows existing project patterns exactly (constructor,
OneToNOpAdaptoralias, boilerplate structure). Good consistency. - Stack effect comments on each struct match Forth standard.
- ODS definitions are well-structured with proper summary/description fields.
- Pattern registration list reformatting is a clean diff.
Potential Issues
-
No bounds checking on PICK/ROLL
nvalues — A negative or out-of-rangenwould read/write out of bounds on the 256-element memref. Consistent with the project's design (untyped stack, programmer ensures safety), so not a blocker, but GPU kernels using these words need care. -
ROLL with n=0 — When
n=0,rolledAddr == spAfterPop, so the loop range is empty (zero iterations). The saved value is stored back at the same position. Correct but results in a redundant load/store. Minor, not worth optimizing. -
Puretrait on PICK/ROLL — Fine at the Forth dialect level (pure SSA transformations on!forth.stack). Consistent withSwapOp,RotOp, etc.
Test Coverage
- Translation test (
stack-ops.forth): Verifies all four words parse to correctforth.*ops. ✓ - Conversion test (
stack-manipulation.mlir): Tests MemRef lowering with CHECK patterns covering all load/store/loop sequences. Pushesliteral 2before PICK and ROLL to exercise dynamic indexing. ✓ - Missing: no end-to-end pipeline test in
test/Pipeline/. Not a blocker since conversion tests cover the patterns, but would add confidence.
Suggestions
- Update
CLAUDE.md— TheSupported Wordssection listsDUP DROP SWAP OVER ROTbut does not includeNIP, TUCK, PICK, ROLL. Should be updated to keep docs in sync. - Consider a pipeline test (optional, low priority).
LGTM with the documentation nit. 👍
Summary
scf.forshift loopCloses #7
Test plan
check-warpforthpasses (35/35)forth.*ops